require 'enumerator'
require 'wiki_plugin'

class Renderer

  # アクセサ
  attr_accessor :content
  attr_accessor :params

  #
  # 基本的に空行でブロック単位に区切りますが、例外をサブクラスで指定できます。
  # array @single_line_elements
  #
  def initialize()
    @single_line_elements = []
  end

  #
  # ブロックに分割されたwikiテキストのレンダリングを行う
  # ex)
  #
  # input:
  # =タイトル
  #
  # output:
  # <div class="block" id="0">
  # <div class="renderd_html">
  # <h1>タイトル</h1>
  # </div>
  # <input type="hidden" name="block[0]" value="=タイトル" />
  # </div>
  #
  def to_html_with_block(content, options = {})
    @content = content
    @params = options[:params] || {}

    wiki_text = content.body

    # wikiテキストをブロックに分割して配列に格納する
    wiki_blocks = self.split wiki_text

#    WikiPlugin.init

    # ブロックに分割した wikiテキストをhtmlに変換する
    html_blocks = wiki_blocks.enum_with_index.map do |wiki_block, block_id|
      self.make_html_block(wiki_block, content.id.to_s + '_' + block_id.to_s) do
        # wikiをHTMLに変換
        wiki_block = self.to_html wiki_block
      end
    end

    final
#    WikiPlugin.final
    return html_blocks.join("\n\n")
  end

  #
  # ブロックに分割せずに、wikiテキストのレンダリングを行う
  # ex)
  #
  # input:
  # =タイトル
  #
  # output:
  # <h1>タイトル</h1>
  #
  def to_html_without_block(content, options = {})
    @content = content
    @params = options[:params] || {}

    return self.to_html(content.body)
  end

  #
  # ルールに基づき、wikiテキストを配列に格納します
  # ex)
  #
  # input:
  # aaaa
  #
  # bbb
  #
  # ccc
  # ddd
  #
  # output:
  # ['aaaa','bbb','ccc
  # ddd']
  #
  def split(wiki_text)
    tmp = ''
    blocks = []

    # 改行でwikiテキストを分割する
    wiki_lines = wiki_text.split(/\n\r|\r\n|\r|\n/)

    # 各行ごとに処理を実行
    wiki_lines.each_with_index do |line, key|

      # 単体でブロックになる要素を処理する
      if 0 < (@single_line_elements.select {|e| line.match('^'+e+'.*$')}).size then
        if tmp != '' then
          blocks << tmp.chomp unless tmp == ''
          tmp = ''
        end

        tmp += line + "\n"
        blocks << tmp.chomp unless tmp == ''
        tmp = ''
      elsif line != '' then
        tmp += line + "\n"
      end

      # 配列の最後、もしくは line が空の場合、ブロックを閉じる
      if line == '' || key == wiki_lines.size-1 then

        if tmp != "" then
          blocks << tmp.chomp unless tmp == ''
          tmp = ''
        end
      end
    end

    return blocks
  end

  #
  # wikiテキストとレンダリングしたHTMLを含む１ブロックを返す
  #
  def make_html_block(wiki_text, block_id, &proc)
    # ブロックに分割した wikiテキストをhtmlに変換する
    html_block  = ''
    html_block += '<div class="block" id="'+block_id+'">' + "\n"
    html_block += '<div class="rendered_html">' + "\n"
    html_block += yield
    html_block += '</div>' + "\n"
    html_block += '<input type="hidden" name="block['+block_id+']" class="wiki_text" value="' + CGI.escapeHTML(wiki_text) + '" />' + "\n"
    html_block += '</div>' + "\n"
    return html_block
  end

#  #
#  # プラグインの実行とwikiのレンダリングを行う
#  #
#  def render_with_plugin(wiki_block)
#    # プラグインの検出と実行
#    # contents を1レコードごと渡したい・・・
#    #wiki_block = self.#{plugin} wiki_block
#
#    # wikiレンダリング
#    wiki_block = self.render wiki_block
#  end

#  #
#  # プラグインの実行
#  #
#  def load_plugin(plugin_name)
#    plugin_name
#  end

  def final
  end

  #
  # 保存前にソースを整形する
  #
  def before_save(content, options = {})
    @content = content
    @params = options[:params] || {}

    return self.plastic(content.body)
  end
end
